.486p
.model flat
.code

        include map00.h
        include debug.h
        include empty.h
        include 6502.h
        include kb.h
        include file.h
        include data.h
        include io.h
        include equates.h
        include memory.h

        public mapperinit20
        public diskptr
        public ctrl25
;----------------------------------------------------------------------------
mapperinit20:;          FDS
;----------------------------------------------------------------------------
        mov [read_tbl+10h],offset sram_R        ;map $8000-$dfff to ram
        mov [read_tbl+14h],offset sram_R
        mov [read_tbl+18h],offset sram_R
        mov [write_tbl+10h],offset sram_W
        mov [write_tbl+14h],offset sram_W
        mov [write_tbl+18h],offset sram_W
        mov eax,[ram_ptr]
        mov [memmap+4*4],eax
        mov [memmap+5*4],eax
        mov [memmap+6*4],eax

        mov [memmap+7*4],eax
        mov esi,offset fdsrom                   ;copy bios to ram e000-ffff
        lea edi,[eax+0e000h]
        mov ecx,2000h/4
        rep movsd

        mov [read_tbl+2*4],offset disk_R        ;intercept I/O port access
        mov [write_tbl+2*4],offset disk_W

        mov [scanlinehook],offset hook

        mov eax,[rom_ptr]
        mov [diskside],eax
        mov [diskptr],0

        mov [status2],1                         ;disk out
        mov [changesides],0
        mov [ctrl25],24h                        ;disk inactive

        ret
;----------------------------------------------------------------------------
disk_R:;
;----------------------------------------------------------------------------
        cmp edi,4030h
        jb IO_R
        cmp edi,4037h
        ja void                                 ;ignore sound regs for now
        jmp [fds_read+edi*4-4030h*4]

        align 4
fds_read        dd port30_R
                dd empty_R
                dd port32_R
                dd empty_R
                dd port30_R
                dd port31_R
                dd port32_R
                dd port33_R
;----------------------------------------------------------------------------
disk_W:;
;----------------------------------------------------------------------------
        cmp edi,4020h
        jb IO_W
        cmp edi,402ah
        ja void ;empty_W
        jmp [fds_write+edi*4-4020h*4]

        align 4
fds_write       dd port20_W
                dd port21_W
                dd port22_W
                dd empty_W
                dd empty_W
                dd port25_W
                dd empty_W
                dd empty_W
                dd port24_W
                dd port25_W
                dd port26_W
;----------------------------------------------------------------------------
port20_W:;      irq latch (LSB)
;----------------------------------------------------------------------------
trace tMMC0,al        
        mov byte ptr [latch],al
        ret
;----------------------------------------------------------------------------
port21_W:;      irq latch (MSB)
;----------------------------------------------------------------------------
trace tMMC1,al        
        mov byte ptr [latch+1],al
        mov eax,[latch]
        mov [irqcount],eax
        ret
;----------------------------------------------------------------------------
port22_W:;      irq control
;----------------------------------------------------------------------------
trace tMMC2,al
        mov [ctrl22],al
        ret
;----------------------------------------------------------------------------
port24_W:;      disk write
;----------------------------------------------------------------------------
        test [ctrl25],4
        jnz p240

        mov edi,[diskside]
        add edi,[diskptr]
        mov [edi],al
        inc word ptr [diskptr]
p240:
        ret
;----------------------------------------------------------------------------
port25_W:;      control register
;----------------------------------------------------------------------------
if DEBUG
        or al,al
        jns p251
        or [int_flags],DEBUG2
        mov [debugmsg],offset msg47
p251:
endif
        test al,08h
        call mirror2V

        mov [ctrl25],al

        test al,2
        jz p250
        mov [diskptr],0         ;disk reset when bit1=1
p250:
        ret
;----------------------------------------------------------------------------
port26_W:;      expansion out
;----------------------------------------------------------------------------
        ret
;----------------------------------------------------------------------------
port30_R:;      disk status
;----------------------------------------------------------------------------
        mov al,[status1]
trace tMMC4,al

        and [int_flags],not IRQ ;timer irq ack
        and [status1],not 1
        and [ctrl22],not 2      ;stop timer

        ret
;----------------------------------------------------------------------------
port31_R:;      disk read
;----------------------------------------------------------------------------
        test [ctrl25],4
        jz p310

        mov edi,[diskside]
        add edi,[diskptr]
        mov al,[edi]
        inc word ptr [diskptr]
p310:
        ret
;----------------------------------------------------------------------------
port32_R:;      disk status
;----------------------------------------------------------------------------
        mov al,[status2]
        ret
;----------------------------------------------------------------------------
port33_R:;      expansion in+battery
;----------------------------------------------------------------------------
        mov al,80h
        ret
;----------------------------------------------------------------------------
hook:
;----------------------------------------------------------------------------
        test [ctrl22],2
        jz h2
        sub [irqcount],114
        jnc h2
        or [int_flags],IRQ
        or [status1],1
h2:
        mov eax,dword ptr [kb_table+KB_1]       ;check keys 1-4
        or eax,eax
        jz h0
        bsf edi,eax             ;edi=#*8
        shl edi,13
        cmp edi,[romsize]
        jae h1                          ;skip if side not used
        add edi,[rom_ptr]
        mov [diskside],edi
        or [status2],1          ;disk out
        mov [changesides],1
h1:     ret
h0:
        cmp [changesides],1
        jne h3
        mov [changesides],0
        and [status2],not 1     ;disk in
h3:     ret
;----------------------------------------------------------------------------
        align 4

irqcount        dd ?            ;irq count
latch           dd 0            ;irq counter latch

diskside        dd ?            ;ptr to disk#
diskptr         dd ?            ;head position

ctrl22          db ?            ;irq control
ctrl25          db -1           ;drive control
status1         db ?            ;4030
status2         db ?            ;4032
changesides     db ?            ;changing disk

fdsrom:
        include fdsrom.txt
;----------------------------------------------------------------------------
        end
